<?php

/*
 *  Copyright 2007 Genoworks
 *  
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *  
 *      http://www.apache.org/licenses/LICENSE-2.0
 *  
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License. 
 */

 class RetrieverClient {
  var $retrieverHost;
  var $retrieverPort;
  function RetrieverClient( $host, $port ) {
    if ( isset( $host ) == FALSE ) {
      print "host should be specified.";
    } else {
      $this->retrieverHost = $host;
    }
    if ( isset( $port ) ) {
      $this->retrieverPort = $port;
    } else {
      $this->retrieverPort = 1234; // default port number
    }
  }
  function request( $xml ) {

    // Use curl
    $ch = curl_init();
    curl_setopt( $ch, CURLOPT_URL, "http://" . $this->retrieverHost . ":" . $this->retrieverPort . "/xml-api" );
    curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
    curl_setopt( $ch, CURLOPT_TIMEOUT, 4 );
    curl_setopt( $ch, CURLOPT_POSTFIELDS, $xml );

    //
    $result = curl_exec( $ch );

    //
    if ( curl_errno( $ch ) ) {
      print curl_error( $ch );
    } else {
      curl_close( $ch );
    }

    //
    $handler = new RetrieverParseHandler;
    return $handler->parse( $result );
  }
  function open( $id, $dir ) {
    $result = $this->request( '<?xml version="1.0" encoding="UTF-8" ?><list />' );
    $indexList = explode( ',', $result->resultValue );
    for ( $i=0; $i<count( $indexList ); $i += 1 ) {
      if ( $id == $indexList[ $i ] ) {
        return TRUE;
      }
    }
    $result = $this->request( '<?xml version="1.0" encoding="UTF-8" ?>'
        . '<open index-id="' . $id . '" dir="' . $dir . '" />' );
    return $result->isError() == FALSE;
  }
}

class RetrieverResult {
  var $resultCode;
  var $resultMessage;
  var $resultException;
  var $resultValue;
  var $resultTotalCount;
  var $resultDocs;
  function isError() {
    return $this->resultCode >= 100;
  }
  function isSearchResult() {
    return $this->isError()==FALSE && isset( $this->resultTotalCount ) && isset( $this->resultDocs );
  }
}

class RetrieverResultDoc {
  var $key;
  var $fieldArray;
  var $score;
}

class RetrieverParseHandler {
  var $result;
  var $tempCharacters;
  var $tempDoc;
  var $tempFieldName;
  function parse( $str ) {

    //
    $xmlParser = xml_parser_create();
    xml_set_element_handler( $xmlParser, array( &$this, "startElement" ), array( &$this, "endElement" ) );
    xml_set_character_data_handler( $xmlParser, array( &$this, "characters" ) );

    //
    if ( !xml_parse( $xmlParser, $str, TRUE ) ) {
      die( sprintf( "XML error: %s at line %d",
          xml_error_string( xml_get_error_code( $xmlParser ) ),
          xml_get_current_line_number( $xmlParser ) ) );
    }

    //
    xml_parser_free( $xmlParser );

    //
    return $this->result;
  }
  function startElement( $parser, $name, $attrs ) {
    $nameLower = strtolower( $name );
    if ( $nameLower == "reply" ) {
      $this->result = new RetrieverResult;
    } else if ( $nameLower == "docs" ) {
      $this->result->resultDocs = array();
      $this->result->resultTotalCount = $attrs[ "TOTAL-COUNT" ];
      $this->result->resultTotalPages = $attrs[ "TOTAL-PAGES" ];
    } else if ( $nameLower == "doc" ) {
      $this->tempDoc = new RetrieverResultDoc;
      $this->tempDoc->score = $attrs[ "SCORE" ];
      $this->tempDoc->fieldArray = array();
    } else if ( $nameLower == "terms" ) {
      $this->result->resultTerms = array();
      $this->result->resultTotalCount = $attrs[ "TOTAL-COUNT" ];
      unset( $this->tempCharacters );
    } else if ( $nameLower == "field" ) {
      unset( $this->tempCharacters );
      $this->tempFieldName = strtolower( $attrs[ "NAME" ] );
    }
  }
  function endElement( $parser, $name ) {
    $nameLower = strtolower( $name );
    if ( $nameLower == "code" ) {
      $this->result->resultCode = trim( $this->tempCharacters );
      unset( $this->tempCharacters );
    } else if ( $nameLower == "message" ) {
      $this->result->resultMessage = trim( $this->tempCharacters );
      unset( $this->tempCharacters );
    } else if ( $nameLower == "value" ) {
      $this->result->resultValue = trim( $this->tempCharacters );
      unset( $this->tempCharacters );
    } else if ( $nameLower == "doc" ) {
      array_push( $this->result->resultDocs, $this->tempDoc );
      unset( $this->tempDoc );
    } else if ( $nameLower == "term" ) {
      if ( isset( $this->tempCharacters ) ) {
        $this->tempCharacters = trim( $this->tempCharacters );
        if ( strlen( $this->tempCharacters ) > 0 ) {
          array_push( $this->result->resultTerms, $this->tempCharacters );
        }
      }
      unset( $this->tempCharacters );
    } else if ( $nameLower == "field" ) {
      if ( isset( $this->tempCharacters ) ) {
        $this->tempDoc->fieldArray[ $this->tempFieldName ] = $this->tempCharacters;
      }
      unset( $this->tempFieldName, $this->tempCharacters );
    } else if ( $nameLower == "exception" ) {
      $this->result->resultException = trim( $this->tempCharacters );
      unset( $this->tempCharacters );
    }  }
  function characters( $parser, $data ) {
    if ( isset( $this->tempCharacters ) ) {
      $this->tempCharacters .= $data;
    } else {
      $this->tempCharacters = $data;
    }
  }
}

?>